package com.etlmaster.rowprocessor.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Map;

import com.etlmaster.executor.utils.JsonHelper;
import com.etlmaster.executor.utils.LogWriter;



/**
 * @author Larry
 * @copyright Larry@etlMaster
 * @since 2017-09-10
 */
public class ReflectionUtil {

	@SuppressWarnings("unchecked")
	public static <T> T  createInstance(String id,String jobId,String name,String code,String className,Map paramStr,Map var){
		try{
			Class clazz = null;
			
			if(clazz == null){
				clazz =  Class.forName(className);
			}

			Constructor<T> constructor=(Constructor<T>) clazz.getConstructor(String.class,String.class,String.class,String.class,Map.class,Map.class);
			return constructor.newInstance(id,jobId,name,code,paramStr,var);
		} 
		catch(Exception e){
			e.printStackTrace();
			LogWriter.addLog("ERROR","Exception occurs when creating " + className +" {}", e.getMessage());
			return null;
		}
	}
	public static void parseParam(String paramStr,Object obj){
		if(paramStr!=null && paramStr.length()>0){
			paramStr = paramStr.replaceAll("[\\t\\n]","");
			char firstChar = paramStr.charAt(0);
			if(firstChar=='[' || firstChar=='{'){//代表是json对象
				
				Map<String,Object> paramMap = (Map<String,Object>)JsonHelper.getInstance().read(paramStr);
				parseParam(paramMap,obj);
			}
		}
	}
	public static void parseParam(Map<String,Object> paramMap,Object obj){
		if(paramMap!=null && paramMap.size()>0){
			for (Iterator iterator = paramMap.entrySet().iterator(); iterator.hasNext();) {
					Class cls = obj.getClass();
					Map.Entry<String, Object> entry = (Map.Entry<String, Object>) iterator.next();
					
					String key = entry.getKey();
					Field field = null;
					while (field == null) {
						try {
							field = cls.getDeclaredField(key);//这个类的声明中定义的指定名称的属性，这个属性必须是在这个类的声明中定义，可以使私有和保护的,但是所有父类的属性都不会被返回
							if( field!=null ){
								field.setAccessible(true);
								if((field.getType() == Boolean.class || field.getType() == boolean.class)&& entry.getValue().toString().equalsIgnoreCase("true")){
									field.set(obj, true);
								}else if((field.getType() == int.class || field.getType() == Integer.class) && (entry.getValue().getClass()==String.class && StringUtil.isNumberic(entry.getValue().toString()))){
									field.set(obj, Integer.valueOf(entry.getValue().toString()));
								}else if((field.getType() == double.class || field.getType() == Double.class) && (entry.getValue().getClass()==String.class && StringUtil.isNumberic(entry.getValue().toString()))){
									field.set(obj, Double.valueOf(entry.getValue().toString()));
								}else if((field.getType() == long.class || field.getType() == Long.class) && (entry.getValue().getClass()==String.class && StringUtil.isNumberic(entry.getValue().toString()))){
									field.set(obj, Long.valueOf(entry.getValue().toString()));
								}else if(field.getType().isInstance(entry.getValue())){
									field.set(obj, entry.getValue());
								}
							}
						} catch (NoSuchFieldException e) {
//						e.printStackTrace();
						} catch (SecurityException e) {
							e.printStackTrace();
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						} catch (IllegalAccessException e) {
							e.printStackTrace();
						}finally{
							cls = cls.getSuperclass();
							if(cls.getName().equals("java.lang.Object") ){
								break;
							}
						}
					}
				}
			}
		
	}
}
